package aop;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author 26029
 * @date 2025/4/14
 * @description
 */
public class LearnAOP {
    String content;

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        // 获取类对象的四种方式
        // 1.
        Class<?> learn1 = LearnAOP.class;
        System.out.println(learn1);
        // 2.
        Class<?> learn2 = Class.forName("aop.LearnAOP");
        System.out.println(learn2);
        // 3.
        LearnAOP learnAOP = new LearnAOP();
        Class<?> learn3 = learnAOP.getClass();
        System.out.println(learn3);
        // 4.
        Class<?> learn4 = ClassLoader.getSystemClassLoader().loadClass("aop.LearnAOP");
        System.out.println(learn4);

        // 反射获取类
        Class<?> aClass = Class.forName("aop.TargetObject");
        // 获取一个类的对象:一个是获取TargetObject类，一个是获取已知的这个类
        TargetObject object = (TargetObject) aClass.getConstructor().newInstance();
        LearnAOP turnObject = (LearnAOP) aClass.getConstructor().newInstance();
        // 获取所有方法
        Method[] methods = aClass.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
        }
        // 调用指定方法
        Method publicMethod = aClass.getDeclaredMethod("publicMethod", String.class);
        publicMethod.invoke(object, "Learn Java AOP");
        // 获取所有字段
        Field[] fields = aClass.getDeclaredFields();
        for(Field field : fields) {
            System.out.println(field.getName());
        }
        // 对指定成员变量取消安全检查
        Field field = aClass.getDeclaredField("value");
        // 为了对类中的参数进行修改我们取消安全检查，private的也能拿到了
        field.setAccessible(true);
        field.set(object, "更新值");
        System.out.println(field.get(object));
        // 调用private方法
        Method privateMethod = aClass.getDeclaredMethod("privateMethod");
        privateMethod.setAccessible(true);
        privateMethod.invoke(object);
    }

    LearnAOP() {
        this.content = "这是一个AOP学习类";
    }
}

class TargetObject {
    private String value;

    public TargetObject() {
        value = "初始值";
    }

    public void publicMethod(String s) {
        System.out.println("I love " + s);
    }

    private void privateMethod() {
        System.out.println("value is " + value);
    }
}